import junit.framework.TestCase;
import java.util.*;

import navalgo3.Modelo.Buque;
import navalgo3.Modelo.Destructor;
import navalgo3.Modelo.Fragmento;
import navalgo3.Modelo.Lancha;
import navalgo3.Modelo.Mina;
import navalgo3.Modelo.MinaDobleConRetardo;
import navalgo3.Modelo.MinaPorContacto;
import navalgo3.Modelo.MinaTripleConRetardo;
import navalgo3.Modelo.Norte;
import navalgo3.Modelo.Portaaviones;
import navalgo3.Modelo.Posicion;
import navalgo3.Modelo.Rompehielos;


public class MinaTests extends TestCase {

        public void testSeColocaMinaDobleYAlExplotarCreaFragmentos() {
                Posicion posicionMina = new Posicion(2,2);
               
                MinaDobleConRetardo minaActual = new MinaDobleConRetardo(posicionMina);
                minaActual.explotar();
                ArrayList <Fragmento> fragmentos = minaActual.getFragmentos(); 
                assertTrue (fragmentos.get(0).estaUbicadoEn(new Posicion(1,1)));
                assertTrue (fragmentos.get(1).estaUbicadoEn(new Posicion(1,2)));
                assertTrue (fragmentos.get(2).estaUbicadoEn(new Posicion(1,3)));
                assertTrue (fragmentos.get(3).estaUbicadoEn(new Posicion(2,1)));
                assertTrue (fragmentos.get(4).estaUbicadoEn(new Posicion(2,2)));
                assertTrue (fragmentos.get(5).estaUbicadoEn(new Posicion(2,3)));
                assertTrue (fragmentos.get(6).estaUbicadoEn(new Posicion(3,1)));
                assertTrue (fragmentos.get(7).estaUbicadoEn(new Posicion(3,2)));
                assertTrue (fragmentos.get(8).estaUbicadoEn(new Posicion(3,3)));
                assertFalse (fragmentos.get(4).estaUbicadoEn(new Posicion(1,1)));
                           
        }

		public void testSeColocaMinaTripleYAlExplotarCreaFragmentos() {
			Posicion posicionMina = new Posicion(5,5);
			MinaTripleConRetardo minaActual = new MinaTripleConRetardo(posicionMina);
			minaActual.explotar();
			ArrayList <Fragmento> fragmentos = minaActual.getFragmentos();
			assertTrue (fragmentos.get(0).estaUbicadoEn(new Posicion(3,3)));
			assertTrue (fragmentos.get(1).estaUbicadoEn(new Posicion(3,4)));
			assertTrue (fragmentos.get(2).estaUbicadoEn(new Posicion(3,5)));
			assertTrue (fragmentos.get(3).estaUbicadoEn(new Posicion(3,6)));
			assertTrue (fragmentos.get(4).estaUbicadoEn(new Posicion(3,7)));
			assertTrue (fragmentos.get(5).estaUbicadoEn(new Posicion(4,3)));
			assertTrue (fragmentos.get(6).estaUbicadoEn(new Posicion(4,4)));
			assertTrue (fragmentos.get(7).estaUbicadoEn(new Posicion(4,5)));
			assertTrue (fragmentos.get(8).estaUbicadoEn(new Posicion(4,6)));
			assertTrue (fragmentos.get(9).estaUbicadoEn(new Posicion(4,7)));
			assertTrue (fragmentos.get(10).estaUbicadoEn(new Posicion(5,3)));
			assertTrue (fragmentos.get(11).estaUbicadoEn(new Posicion(5,4)));
			assertTrue (fragmentos.get(12).estaUbicadoEn(new Posicion(5,5)));
			assertTrue (fragmentos.get(13).estaUbicadoEn(new Posicion(5,6)));
			assertTrue (fragmentos.get(14).estaUbicadoEn(new Posicion(5,7)));
			assertTrue (fragmentos.get(15).estaUbicadoEn(new Posicion(6,3)));
			assertTrue (fragmentos.get(16).estaUbicadoEn(new Posicion(6,4)));
			assertTrue (fragmentos.get(17).estaUbicadoEn(new Posicion(6,5)));
			assertTrue (fragmentos.get(18).estaUbicadoEn(new Posicion(6,6)));
			assertTrue (fragmentos.get(19).estaUbicadoEn(new Posicion(6,7)));
			assertTrue (fragmentos.get(20).estaUbicadoEn(new Posicion(7,3)));
			assertTrue (fragmentos.get(21).estaUbicadoEn(new Posicion(7,4)));
			assertTrue (fragmentos.get(22).estaUbicadoEn(new Posicion(7,5)));
			assertTrue (fragmentos.get(23).estaUbicadoEn(new Posicion(7,6)));
			assertFalse (fragmentos.get(24).estaUbicadoEn(new Posicion(7,1)));
		}
		
		public void testMinaSimpleDaniaLancha(){
			Mina unaMinaSimple = new MinaPorContacto(new Posicion(5,5));
			ArrayList<Posicion> posicionDeNave = new ArrayList<Posicion>();
			posicionDeNave.add(new Posicion (5,5));
			posicionDeNave.add(new Posicion (5,6));
			Lancha unaLancha = new Lancha(posicionDeNave, new Norte());
			unaMinaSimple.explotar();
			ArrayList<Fragmento> fragmentosAlExplotar = unaMinaSimple.getFragmentos();
			for (int i=0;i<fragmentosAlExplotar.size();i++){
				if (unaLancha.tieneParteEn(fragmentosAlExplotar.get(i).getPosicion())){
					unaLancha.recibirImpacto(fragmentosAlExplotar.get(i));
				}
			}
			
			assertTrue(unaLancha.tieneDanioEn(new Posicion (5,5)));
			}
		
		public void testMinaSimpleDaniaRompehielos(){
			Mina unaMinaSimple = new MinaPorContacto(new Posicion(5,5));
			ArrayList<Posicion> posicionDeNave = new ArrayList<Posicion>();
			posicionDeNave.add(new Posicion (5,5));
			posicionDeNave.add(new Posicion (5,6));
			posicionDeNave.add(new Posicion (5,7));
			Rompehielos unRompehielos = new Rompehielos(posicionDeNave, new Norte());
			unaMinaSimple.explotar();
			ArrayList<Fragmento> fragmentosAlExplotar = unaMinaSimple.getFragmentos();
			for (int i=0;i<fragmentosAlExplotar.size();i++){
				if (unRompehielos.tieneParteEn(fragmentosAlExplotar.get(i).getPosicion())){
					unRompehielos.recibirImpacto(fragmentosAlExplotar.get(i));
				}
			}
			
			assertTrue(unRompehielos.tieneDanioEn(new Posicion (5,5)));
			}
		
		public void testMinaDestruyeBuque(){
			Mina unaMinaSimple = new MinaPorContacto(new Posicion(5,5));
			ArrayList<Posicion> posicionDeNave = new ArrayList<Posicion>();
			posicionDeNave.add(new Posicion (5,5));
			posicionDeNave.add(new Posicion (5,6));
			posicionDeNave.add(new Posicion (5,7));
			posicionDeNave.add(new Posicion (5,8));
			Buque unBuque = new Buque(posicionDeNave, new Norte());
			unaMinaSimple.explotar();
			ArrayList<Fragmento> fragmentosAlExplotar = unaMinaSimple.getFragmentos();
			for (int i=0;i<fragmentosAlExplotar.size();i++){
				if (unBuque.tieneParteEn(fragmentosAlExplotar.get(i).getPosicion())){
					unBuque.recibirImpacto(fragmentosAlExplotar.get(i));
				}
			}
			
			assertTrue(unBuque.estaDestruida());
			}
		
		public void testMinaSimpleDaniaPortaaviones(){
			Mina unaMinaSimple = new MinaPorContacto(new Posicion(5,5));
			ArrayList<Posicion> posicionDeNave = new ArrayList<Posicion>();
			posicionDeNave.add(new Posicion (5,5));
			posicionDeNave.add(new Posicion (5,6));
			posicionDeNave.add(new Posicion (5,7));
			posicionDeNave.add(new Posicion (5,8));
			posicionDeNave.add(new Posicion (5,9));
			Portaaviones unPortaaviones = new Portaaviones(posicionDeNave, new Norte());
			unaMinaSimple.explotar();
			ArrayList<Fragmento> fragmentosAlExplotar = unaMinaSimple.getFragmentos();
			for (int i=0;i<fragmentosAlExplotar.size();i++){
				if (unPortaaviones.tieneParteEn(fragmentosAlExplotar.get(i).getPosicion())){
					unPortaaviones.recibirImpacto(fragmentosAlExplotar.get(i));
				}
			}
			
			assertTrue(unPortaaviones.tieneDanioEn(new Posicion (5,5)));
			}
		
		public void testMinaExplotaPeroNoDaniaDestructor(){
			Mina unaMinaSimple = new MinaPorContacto(new Posicion(5,5));
			ArrayList<Posicion> posicionDeNave = new ArrayList<Posicion>();
			posicionDeNave.add(new Posicion (5,5));
			posicionDeNave.add(new Posicion (5,6));
			posicionDeNave.add(new Posicion (5,7));
			Destructor unDestructor = new Destructor(posicionDeNave, new Norte());
			unaMinaSimple.explotar();
			ArrayList<Fragmento> fragmentosAlExplotar = unaMinaSimple.getFragmentos();
			for (int i=0;i<fragmentosAlExplotar.size();i++){
				if (unDestructor.tieneParteEn(fragmentosAlExplotar.get(i).getPosicion())){
					unDestructor.recibirImpacto(fragmentosAlExplotar.get(i));
				}
			}
			
			assertFalse(unDestructor.tieneDanioEn(new Posicion (5,5)));
			}
		
		public void testMinaDobleDaniaLanchaPeroNoLaDestruye(){
			Mina unaMinaDoble = new MinaDobleConRetardo(new Posicion(5,5));
			ArrayList<Posicion> posicionDeNave = new ArrayList<Posicion>();
			posicionDeNave.add(new Posicion (6,5));
			posicionDeNave.add(new Posicion (7,5));
			Lancha unaLancha = new Lancha(posicionDeNave, new Norte());
			unaMinaDoble.explotar();
			ArrayList<Fragmento> fragmentosAlExplotar = unaMinaDoble.getFragmentos();
			for (int i=0;i<fragmentosAlExplotar.size();i++){
				if (unaLancha.tieneParteEn(fragmentosAlExplotar.get(i).getPosicion())){
					unaLancha.recibirImpacto(fragmentosAlExplotar.get(i));
				}
			}
			
			assertTrue(unaLancha.tieneDanioEn(new Posicion (6,5)));
			assertFalse (unaLancha.tieneDanioEn(new Posicion (7,5)));
		}
		
		public void testMinaDobleDestruyeLancha(){
			Mina unaMinaDoble = new MinaDobleConRetardo(new Posicion(5,5));
			ArrayList<Posicion> posicionDeNave = new ArrayList<Posicion>();
			posicionDeNave.add(new Posicion (5,5));
			posicionDeNave.add(new Posicion (5,6));
			Lancha unaLancha = new Lancha(posicionDeNave, new Norte());
			unaMinaDoble.explotar();
			ArrayList<Fragmento> fragmentosAlExplotar = unaMinaDoble.getFragmentos();
			for (int i=0;i<fragmentosAlExplotar.size();i++){
				if (unaLancha.tieneParteEn(fragmentosAlExplotar.get(i).getPosicion())){
					unaLancha.recibirImpacto(fragmentosAlExplotar.get(i));
				}
			}
			
			assertTrue(unaLancha.estaDestruida());
			}

		
		public void testMinaTripleExplotaPeroNoDaniaDestructor(){
			Mina unaMinaDoble = new MinaDobleConRetardo(new Posicion(5,5));
			ArrayList<Posicion> posicionDeNave = new ArrayList<Posicion>();
			posicionDeNave.add(new Posicion (5,5));
			posicionDeNave.add(new Posicion (5,6));
			posicionDeNave.add(new Posicion (5,7));
			Destructor unaDestructor = new Destructor(posicionDeNave, new Norte());
			unaMinaDoble.explotar();
			ArrayList<Fragmento> fragmentosAlExplotar = unaMinaDoble.getFragmentos();
			for (int i=0;i<fragmentosAlExplotar.size();i++){
				if (unaDestructor.tieneParteEn(fragmentosAlExplotar.get(i).getPosicion())){
					unaDestructor.recibirImpacto(fragmentosAlExplotar.get(i));
				}
			}
			
			assertFalse(unaDestructor.tieneDanioEn(new Posicion(5,5)));
			assertFalse(unaDestructor.tieneDanioEn(new Posicion(5,6)));
			assertFalse(unaDestructor.tieneDanioEn(new Posicion(5,7)));
		}



}